/**
 * ...
 * @author Krzysztof Rozalski
 */

package hapi.physics.integration.test;
import hapi.math.Angle;
import hapi.math.MathUtil;
import hapi.math.Vector2D;
import hapi.physics.Acceleration;
import hapi.physics.AngularAcceleration;
import hapi.physics.AngularVelocity;
import hapi.physics.integration.Accelerator;
import hapi.physics.integration.EulerIntegration;
import hapi.physics.integration.Integrateable;
import hapi.physics.integration.NumericalIntegrationStrategy;
import hapi.physics.integration.RK4Integration;
import hapi.physics.Time;
import hapi.physics.Velocity;
using hapi.math.AngleFactoryMethods;

using hapi.physics.PhysicsFactoryMethods;

class TestIntegrations {

	public static function main() {
		var t1:Integrateable = createEmptyIntegrateable();
		var t2:Integrateable = createEmptyIntegrateable();
		
		var rk4Integration:NumericalIntegrationStrategy = new RK4Integration(new SimpleAccelerator());
		var eulerIntegration:NumericalIntegrationStrategy = new EulerIntegration(new SimpleAccelerator());
		
		var t = 0.seconds();
		var dt:Time = 1.seconds();
		var duration = 20.seconds();
		#if neko
			haxe.Log.trace = function(msg:Dynamic, ?infos) { neko.Lib.println(msg); }
		#end
		var r = MathUtil.roundTo;
		while (!duration.isNull()) {
			rk4Integration.integrate(t1, t, dt);
			eulerIntegration.integrate(t2, t, dt);
			t.add(dt);
			duration.substract(dt);
			trace(t.seconds + ": " + t1.position + " " + t1.velocity +" "+t1.angle+ " vs " + t2.position + " " + t2.velocity+" "+t1.angle);
		}
	}
	
	static function createEmptyIntegrateable():Integrateable {
		return new Integrateable(new Vector2D(0,0), new Velocity(0, Vector2D.ZERO), 0.radians(), AngularVelocity.zero());
	}
}

class SimpleAccelerator implements Accelerator {
	
	public function new(){}
	
	public function acceleration(target:Integrateable, time:Time):Acceleration {
		return new Acceleration(10, new Vector2D(1, 0));
	}
	
	public function angularAcceleration(target:Integrateable, time:Time):AngularAcceleration {
		return new AngularAcceleration(5);
	}
}